#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>

#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include <liburing.h>

#include "tcp_log.h"
#include "tcp_conn.h"
#include "tcp_iouring.h"


static void __server_ShowUsage(const char* pcName)
{
    printf("Usage: %s\n", pcName);
    printf("\t-?");
    printf("\t-h,              this message\n");
    printf("\t-s,              host name\n");
    printf("\t-p,              listen port\n");
}

void __server_ParseOpt(int argc, char** argv, TCP_SERVER_CONFIG_S* pstConfig)
{
    const char *pcOptStr = "s:p:Vh?";
    int iOpt;
    int iHelp = 0;

    while ((iOpt = getopt(argc, argv, pcOptStr)) != -1) 
    {
		switch (iOpt) {
		case 's':
			pstConfig->pcHostName = strdup(optarg);
			break;
		case 'p':
			pstConfig->usPort = atoi(optarg);
			break;
		case 'V':
			pstConfig->usVerbose = 1;
			break;
		case 'h':
		default:
            iHelp = 1;
			__server_ShowUsage(argv[0]);
			break;
		}
	}

    if (iHelp)
    {
        exit(0);
    }
}



int main(int argc, char** argv)
{
    unsigned int uiQLen = 1024;
    struct io_uring stRing;
    struct io_uring_params stParams = {};

    volatile int iRunFlag = 1;

    TCP_SERVER_S stServer = 
    {
        .iRunFlag = 1,
        .stConfig.pcHostName = "0.0.0.0",
        .stConfig.usPort = 8888,
        .stConfig.usVerbose = 0,
    };

    __server_ParseOpt(argc, argv, &stServer.stConfig);

    int iErr = TCP_iouring_Init(uiQLen);
    if (iErr < 0)
    {
        return 0;
    }

    TCP_CONNECTION_S* pstConn = TCP_conn_CreateListener(stServer.stConfig.pcHostName, stServer.stConfig.usPort);
    if (pstConn == NULL)
    {
        return 0;
    }

    TCP_iouring_AddSQE(pstConn, TCP_CONN_ACCEPT);

    TCP_iouring_Schedule(&stServer);

    TCP_iouring_Exit();

    return 0;
}